package com.linln.admin.meeting.controller;

import com.linln.admin.meeting.domain.Group;
import com.linln.admin.meeting.domain.OrderInfo;
import com.linln.admin.meeting.domain.Room;
import com.linln.admin.meeting.service.DistributeLockComponent;
import com.linln.admin.meeting.service.GroupService;
import com.linln.admin.meeting.service.OrderService;
import com.linln.admin.meeting.service.RoomService;
import com.linln.admin.meeting.validator.OrderValid;
import com.linln.common.enums.StatusEnum;
import com.linln.common.exception.BusinessException;
import com.linln.common.utils.EntityBeanUtil;
import com.linln.common.utils.ResultVoUtil;
import com.linln.common.vo.ResultVo;
import com.linln.component.shiro.ShiroUtil;
import com.linln.modules.system.domain.User;
import com.linln.modules.system.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 预订会议室
 */
@Slf4j
@Controller
@RequestMapping("/meeting/order")
public class OrderController {

    @Autowired
    private RoomService infoService;
    @Autowired
    private GroupService groupService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private UserService userService;

    @Autowired
    private DistributeLockComponent lockComponent;

    /**
     * 预订页面
     */
    @GetMapping("/dashboard")
    @RequiresPermissions("meeting:order:dashboard")
    public String index(Model model) {
        Group g = new Group();
        g.setStatus(StatusEnum.OK.getCode().shortValue());
        model.addAttribute("groups", groupService.getPageList(Example.of(g)));
        model.addAttribute("dates", initDates());
        return "/meeting/order/dashboard";
    }

    /**
     * 列表页面
     */
    @GetMapping("/index")
    @RequiresPermissions("meeting:order:index")
    public String index(Model model, OrderInfo orderInfo) {

        model.addAttribute("users", userService.getAll());
        model.addAttribute("rooms", infoService.getByStatus(StatusEnum.OK));
        // 创建匹配器，进行动态查询匹配
        ExampleMatcher matcher = ExampleMatcher.matching();

        // 获取数据列表
        Example<OrderInfo> example = Example.of(orderInfo, matcher);
        Page<OrderInfo> list = orderService.getPageList(example);

        // 封装数据
        model.addAttribute("list", list.getContent());
        model.addAttribute("page", list);
        return "/meeting/order/index";
    }

    /**
     * 跳转到添加页面
     */
    @GetMapping("/add")
    @RequiresPermissions("meeting:order:add")
    public String toAdd(Model model) {
        model.addAttribute("users",  userService.getAll());
        model.addAttribute("rooms", infoService.getByStatus(StatusEnum.OK));
        return "/meeting/order/add";
    }

    /**
     * 跳转到编辑页面
     */
    @GetMapping("/edit/{id}")
    @RequiresPermissions("meeting:order:edit")
    public String toEdit(@PathVariable("id") OrderInfo orderInfo, Model model) {
        model.addAttribute("orderInfo", orderInfo);
        return "/meeting/order/add";
    }

    /**
     * 保存添加/修改的数据
     *
     * @param valid 验证对象
     */
    @PostMapping("/save")
    @RequiresPermissions({"meeting:order:add", "meeting:order:edit"})
    @ResponseBody
    public ResultVo save(@Validated OrderValid valid, OrderInfo orderInfo) {
        // 复制保留无需修改的数据
        if (orderInfo.getId() != null) {
            OrderInfo beOrderInfo = orderService.getById(orderInfo.getId());
            EntityBeanUtil.copyProperties(beOrderInfo, orderInfo);
        }

        // 保存数据
        orderService.save(orderInfo);
        return ResultVoUtil.SAVE_SUCCESS;
    }

    /**
     * 跳转到详细页面
     */
    @GetMapping("/detail/{id}")
    @RequiresPermissions("meeting:order:room:take")
    public String toDetail(@PathVariable("id") OrderInfo orderInfo, Model model) {
        model.addAttribute("orderInfo", orderInfo);
        model.addAttribute("users",  userService.getAll());
        model.addAttribute("rooms", infoService.getByStatus(StatusEnum.OK));
        return "/meeting/order/detail";
    }

    /**
     * 查询所有会议室信息
     */
    @GetMapping("/room/list")
    @RequiresPermissions("meeting:order:room:take")
    @ResponseBody
    public List<Map> roomList(String groupId, HttpServletResponse response) {
        List<Map> ret = new ArrayList<>();
        List<Room> rooms = infoService.getByGroupId(groupId);
        if (rooms == null) {
            return ret;
        }
        String[] colors = {"#84C1FF", "#02C874", "#00CACA", "#0080FF", "#E1E100", "#82D900", "#6A6AFF", "#82D900"};
        int i = 0;
        for (Room room : rooms) {
            Map<String, Object> one = new HashMap<>();
            one.put("id", room.getId());
            one.put("title", room.getTitle() + "\n(容纳人数：" + room.getVolume() + "; " + room.getDevices() + "; 窗户：" + ("1".equals(room.getWindow()) ? "有" : "无") + ")");
            if (i >= colors.length - 1) {
                i = 0;//再从头取
            }
            String color = colors[i++];
            one.put("color", color);
            one.put("eventColor", color);
            ret.add(one);
        }
        return ret;
    }

    /**
     * 查询所有会议室预订信息
     *
     * @param groupId  分组信息
     * @param start    开始时间
     * @param end      结束时间
     * @param response
     * @return
     */
    @GetMapping("/room/orders")
    @RequiresPermissions("meeting:order:room:take")
    @ResponseBody
    public List<Map> roomOrders(String groupId, String start, String end, HttpServletResponse response) {
        List<Map> ret = new ArrayList<>();
        List<OrderInfo> orders = orderService.getRangeAllMeetings(groupId, start, end);
        if (orders == null) {
            return ret;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        for (OrderInfo order : orders) {
            Map<String, Object> one = new HashMap<>();
            one.put("resourceId", order.getMeetingId());
            one.put("id", order.getId());
            String startTime = sdf.format(order.getStartTime());
            String endTime = sdf.format(order.getEndTime());
            String timeRange = startTime.substring(startTime.length() - 5) + " ~ " + endTime.substring(endTime.length() - 5);
            one.put("title", userService.getById(order.getUserId()).getNickname() + " - " + order.getSubject() + " - " + timeRange);
            one.put("start", startTime);
            one.put("end", endTime);

            ret.add(one);
        }
        return ret;
    }

    /**
     * 先将会议室预订掉
     *
     * @param response
     * @return
     */
    @PostMapping("/room/takeing")
    @RequiresPermissions("meeting:order:room:take")
    @ResponseBody
    public ResultVo roomTaked(Long roomId, String start, String end, HttpServletResponse response) {
        //先将会议室抢了再说

        String lockey = "takeRoomId=" + roomId;
        if (lockComponent.tryLock(lockey)) {
            try {
                OrderInfo order = orderService.takeRoom(roomId, new Date(start), new Date(end));
                return ResultVoUtil.success("操作成功", order);
            } catch (BusinessException e) {
                return ResultVoUtil.error(e.getMessage());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return ResultVoUtil.error("操作失败！");
            } finally {
                lockComponent.releaseLock(lockey);
            }
        } else {
            throw new BusinessException("有人同时预订该会议室");
        }
    }

    /**
     * 跳转到预订页面的修改页面
     */
    @GetMapping("/room/take")
    @RequiresPermissions("meeting:order:room:take")
    public String roomTake(Long orderId,String newFlag, Model model) {
        OrderInfo order = orderService.getById(orderId);
        model.addAttribute("rooms", infoService.getByStatus(StatusEnum.OK));
        model.addAttribute("orderInfo", order);
        model.addAttribute("user", userService.getById(order.getUserId()));
        model.addAttribute("newFlag",newFlag);
        return "/meeting/order/take";
    }

    /**
     * 修改预订信息
     *
     * @param orderInfo
     * @return
     */
    @PostMapping("/room/updatetake")
    @RequiresPermissions({"meeting:order:room:take"})
    @ResponseBody
    public ResultVo roomUpdatetake(OrderInfo orderInfo) {
        // 复制保留无需修改的数据
        if (orderInfo.getId() != null) {
            OrderInfo beOrderInfo = orderService.getById(orderInfo.getId());
            EntityBeanUtil.copyProperties(beOrderInfo, orderInfo);
        }
        // 保存数据
        orderService.save(orderInfo);
        return ResultVoUtil.SAVE_SUCCESS;
    }

    /**
     * 验证是不是自己预订的，返回true或false
     *
     * @param orderId
     * @return
     */
    @PostMapping("/is_self")
    @RequiresPermissions({"meeting:order:room:take"})
    @ResponseBody
    public ResultVo isSelf(Long orderId) {
        OrderInfo orderInfo = orderService.getById(orderId);
        if (orderInfo == null) {
            return ResultVoUtil.error("预约信息不存在！");
        }
        Long curUserId = ShiroUtil.getSubject().getId();
        boolean ret = false;
        if (curUserId.compareTo(orderInfo.getUserId()) == 0) {
            ret = true;
        }
        return ResultVoUtil.success("成功", ret);
    }

    /**
     * 取消指定的预约信息
     *
     * @param orderId
     * @return
     */
    @PostMapping("/cancel")
    @RequiresPermissions({"meeting:order:room:take"})
    @ResponseBody
    public ResultVo cancel(Long orderId) {
        try {
            orderService.cancel(orderId);
            return ResultVoUtil.success();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultVoUtil.error(e.getMessage());
        }
    }


    private List<Map> initDates() {
        List<Map> dates = new ArrayList<>();
        String[] days = {"日", "一", "二", "三", "四", "五", "六"};
        for (int i = 0; i < 7; i++) {
            Map<String, String> date = new HashMap<>();
            String tips = "";
            Calendar day = Calendar.getInstance();
            day.add(Calendar.DATE, i);
            String val = new SimpleDateFormat("yyyy-MM-dd").format(day.getTime());
            String shortDay = days[day.get(Calendar.DAY_OF_WEEK) - 1];
            String dayStr = "(周" + shortDay + ")";
            if (i == 0) {
                tips = "今天";
            } else if (i == 1) {
                tips = "明天";
            } else if (i == 2) {
                tips = "后天";
            } else if (i == -1) {
                tips = "昨天";
            } else if (i == -2) {
                tips = "前天";
            } else {
                tips = val;
            }
            tips = tips + dayStr;
            if (shortDay.equals("日")) {//周日，一般情况下会放假
                tips = "<span style='text-shadow: 0px 1px 1px #c2c2c2;'>" + tips + "</span>";
            }
            date.put("tips", tips);
            date.put("date", val);
            date.put("today", (i == 0 ? "1" : "0"));
            dates.add(date);
        }
        return dates;
    }
}
